import { fetch, fetchByIdOrSid, add, addList, edit, remove } from '@/services/base';
import {  Effect } from 'dva';
import { Reducer } from 'redux';


export interface BaseModelState {
  pageData: any;
  data:any;
  fetchUrl: string;
}
export interface BaseModelType {
  namespace: string;
  state: BaseModelState;
  effects: any;
  reducers: {
    save: Reducer<BaseModelState>;
  };
}
const BaseModel : BaseModelType  = {
  namespace: "base",
  state: {
    pageData: {
      list:[],
      pagination: {},
    },
    data: {},
    fetchUrl: undefined, // 当前分页查询url
  },
  effects: {

    /**======================   基础通用方法   =======================================*/

    /**
     *   基础查询
     */
    *fetch({ payload, callback },{ call, put }) {
      const response = yield call(fetch, payload);
      if(response.statusCode === "0"){
        yield put({ type: 'save', payload: { data : response }});
        if(callback) callback(response);
      }
    },
    /**
     *   分页查询
     *   优化处理： 如果分页查询url发生改变，那么会重置pageData
     */
    *fetchPage({ payload, callback },{ call, put, select  }) {
      const { url } = payload;
      const fetchUrl = yield select(state => state.base.fetchUrl);
      // 分页查询时清除原有数据，避免数据残留问题
      if(url !== fetchUrl){
        yield put({ type: 'save', payload: { pageData: {  list:[], pagination: {} }, fetchUrl: url }});
      }
      const response = yield call(fetch, payload);
      if(response.statusCode === "0"){
        const { records = [], total = 0, current = 1, size = 10 } = response.data;
        const pageData = {
          list: records,
          pagination: {
            current,
            pageSize:size,
            total
          }
        };
        yield put({ type: 'save', payload: { pageData }});
        if(callback) callback(response);
      }
    },
    /**
     *   根据id或者sid查询
     */
    *fetchByIdOrSid({ payload, callback }, { call, put }) {
      const response = yield call(fetchByIdOrSid, payload);
      if(response.statusCode === "0"){
        yield put({ type: 'save', payload: { data : response }});
        if(callback) callback(response);
      }
    },
    /**
     *  新增对象
     */
    *add({ payload, callback }, { call, put }) {
      const response = yield call(add, payload);
      if(response.statusCode === "0"){
        yield put({ type: 'save', payload: { data : response }});
        if(callback) callback(response);
      }
    },
    /**
     *  新增数组   参数名必须是list
     */
    *addList({ payload, callback }, { call, put }) {
      const response = yield call(addList, payload);
      if(response.statusCode === "0"){
        yield put({ type: 'save', payload: { data : response }});
        if(callback) callback(response);
      }
    },
    /**
     *  编辑  参数必须包含id或者sid
     */
    *edit({ payload, callback }, { call, put }) {
      const response = yield call(edit, payload);
      if(response.statusCode === "0"){
        yield put({ type: 'save', payload: { data : response }});
        if(callback) callback(response);
      }
    },
    /**
     *  删除
     */
    *remove({ payload, callback }, { call, put }) {
      const response = yield call(remove, payload);
      if(response.statusCode === "0"){
        yield put({ type: 'save', payload: { data : response }});
        if(callback) callback(response);
      }
    },


    /**================  以下的方法会直接返回response,当不论结果都需要使用回调函数时使用    ============================*/

    /**
     *  get方法不论结果都使用回调
     */
    *fetchWithRes({ payload, callback },{ call, put }) {
      const response = yield call(fetch, payload);
      yield put({ type: 'save', payload: { data : response }});
      callback(response);
    },
    /**
     *  post方法不论结果都使用回调
     */
    *addWithRes({ payload, callback },{ call, put }) {
      const response = yield call(add, payload);
      yield put({ type: 'save', payload: { data : response }});
      callback(response);
    },
    /**
     *  delete方法不论结果都使用回调
     */
    *removeWithRes({ payload, callback }, { call, put }) {
      const response = yield call(remove, payload);
      yield put({ type: 'save', payload: { data : response }});
      callback(response);
    },


  },

  reducers: {
    save(state,action) {
      return {
        ...state,
        ...action.payload,
      };
    }
  },
};
export default BaseModel;
